#include <filter_pattern.h>
#include <algorithm>

Person::Person(string name, string gender, string maritalStatus)
{
    this->name = name;
    this->gender = gender;
    this->maritalStatus = maritalStatus;
}

string Person::getName()
{
    return this->name;
}

string Person::getGender()
{
    return this->gender;
}

string Person::getMaritalStatus()
{
    return this->maritalStatus;
}

vector<Person*> CriteriaMale::meetCriteria(vector<Person*> persons)
{
    vector<Person*> malePersons;
    vector<Person*>::iterator it = persons.begin();
    for(; it < persons.end(); it++)
    {
        if((*it)->getGender() == "Male")
        {
            malePersons.push_back(*it);
        }
    }
    return malePersons;
}

vector<Person*> CriteriaFemale::meetCriteria(vector<Person *> persons)
{
    vector<Person*> femalePersons;
    vector<Person*>::iterator it = persons.begin();
    for(; it < persons.end(); it++)
    {
        if((*it)->getGender() == "Female")
        {
            femalePersons.push_back(*it);
        }
    }
    return femalePersons;
}

vector<Person*> CriteriaSingle::meetCriteria(vector<Person *> persons)
{
    vector<Person*> singlePersons;
    vector<Person*>::iterator it = persons.begin();
    for(; it < persons.end(); it++)
    {
        if((*it)->getMaritalStatus() == "Single")
        {
            singlePersons.push_back(*it);
        }
    }
    return singlePersons;
}

AndCriteria::AndCriteria(Criteria* criteria, Criteria* otherCriteria)
{
    this->criteria = criteria;
    this->otherCriteria = otherCriteria;
}

vector<Person*> AndCriteria::meetCriteria(vector<Person *> persons)
{
    vector<Person*> firstCriteriaPersons = this->criteria->meetCriteria(persons);
    return this->otherCriteria->meetCriteria(firstCriteriaPersons);
}

OrCriteria::OrCriteria(Criteria* criteria, Criteria* otherCriteria)
{
    this->criteria = criteria;
    this->otherCriteria = otherCriteria;
}

vector<Person*> OrCriteria::meetCriteria(vector<Person *> persons)
{
    vector<Person*> firstCriteriaItems = this->criteria->meetCriteria(persons);
    vector<Person*> otherCriteriaItems = this->otherCriteria->meetCriteria(persons);

    vector<Person*>::iterator it = otherCriteriaItems.begin();
    for(; it < otherCriteriaItems.end(); it++)
    {
        if(!(find(firstCriteriaItems.begin(), firstCriteriaItems.end(), *it) != firstCriteriaItems.end()))
        {
            firstCriteriaItems.push_back(*it);
        }
    }
    return firstCriteriaItems;
}
